package org.pfc.porlapatilla.controllers;

import java.util.List;

import org.pfc.porlapatilla.DTO.MessageDTO;
import org.pfc.porlapatilla.DTO.ResultDTO;
import org.pfc.porlapatilla.model.Message;
import org.pfc.porlapatilla.services.MessageService;
import org.pfc.porlapatilla.services.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * This Controller manages requests related to messages
 * 
 * @author jorgepolobermudez
 * 
 */
@Controller
@RequestMapping("/messages")
public class MessageController {

    private static final Logger logger = LoggerFactory
	    .getLogger(MessageController.class);

    /**
     * The MessageService instance.
     */
    @Autowired
    private MessageService messageService;
    
    /**
     * The UserService instance.
     */
    @Autowired
    private UserService userService;

    /**
     * Find all stored messages.
     * 
     * @param page
     *            Page number.
     * @param size
     *            Size of page.
     * @return The list of <strong>size</strong> messages in the page
     *         <strong>page</strong>.
     */
    @RequestMapping(method = RequestMethod.GET)
    public @ResponseBody
    List<Message> getMessagesPage(
	    @RequestParam(value = "page", required = false) Integer page,
	    @RequestParam(value = "size", required = false) Integer size) {

	if (page == null || size == null) {
	    logger.info("Retrieving all messages");
	    return messageService.findAll();
	}

	logger.info("Retrieving messages: page {" + page + "}, page size {"
		+ size + "}");
	return messageService.findAll(page, size);
    }

    /**
     * Find stored message by id.
     * 
     * @param id
     *            The message id.
     * @return The found message.
     */
    @RequestMapping(value = "/{id}")
    public @ResponseBody
    MessageDTO getMessageById(@PathVariable String id) {
	logger.info("Retrieving message by id");

	return messageService.findById(id);
    }

    /**
     * Find stored messages by sender nick.
     * 
     * @param nick
     *            The sender nick.
     * @param page
     *            Page number.
     * @param size
     *            Size of page.
     * @return The list of <strong>size</strong> messages in the page
     *         <strong>page</strong>.
     */
    @RequestMapping(value = "/sender/{nick}")
    public @ResponseBody
    List<MessageDTO> getMessagesBySender(@PathVariable String nick,
	    @RequestParam(value = "page", required = true) Integer page,
	    @RequestParam(value = "size", required = true) Integer size) {
	logger.info("Retrieving messages by sender: page {" + page
		+ "}, page size {" + size + "}");
	String id = userService.findByNick(nick).getId();
	return messageService.findBySender(id, page, size);
    }

    /**
     * Find stored messages by receiver nick.
     * 
     * @param nick
     *            The receiver nick.
     * @param page
     *            Page number.
     * @param size
     *            Size of number.
     * @return The list of <strong>size</strong> messages in the page
     *         <strong>page</strong>.
     */
    @RequestMapping(value = "/receiver/{nick}")
    public @ResponseBody
    List<MessageDTO> getMessagesByReceiver(@PathVariable String nick,
	    @RequestParam(value = "page", required = true) Integer page,
	    @RequestParam(value = "size", required = true) Integer size) {
	logger.info("Retrieving messages by receiver: page {" + page
		+ "}, size {" + size + "}");
	String id = userService.findByNick(nick).getId();
	return messageService.findByReceiver(id, page, size);
    }

    /**
     * Create a new <strong>message</strong>
     * 
     * @param messageDTO
     * @return The new <strong>message</strong>'s id
     */
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public @ResponseBody
    ResultDTO addMessage(@RequestBody MessageDTO messageDTO) {
	String messageId = messageService.store(messageDTO);
	if (messageId == null) {
	    return new ResultDTO(ResultDTO.RESULT_ERROR, ResultDTO.RESULT_ERROR_MESSAGE_SEND);
	}
	return new ResultDTO(ResultDTO.RESULT_OK, null);
    }

    /**
     * Update an <strong>message</strong>
     * 
     * @param messageDTO
     *            The <strong>message</strong> to update
     * @return The updated <strong>message</strong> id
     */
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public @ResponseBody
    String updateMessage(@RequestBody MessageDTO messageDTO) {
	return messageService.store(messageDTO);
    }
    
    @RequestMapping(value ="/delete/{id}", method = RequestMethod.POST)
    public @ResponseBody
    ResultDTO deleteMessage(@PathVariable String id) {
	ResultDTO resultDTO = new ResultDTO();
	boolean deleted = messageService.delete(id);
	if (deleted) {
	    resultDTO.setResult(ResultDTO.RESULT_OK);
	} else {
	    resultDTO.setResult(ResultDTO.RESULT_ERROR);
	    resultDTO.setError(ResultDTO.RESULT_ERROR_STORE);
	}
	
	return resultDTO;
    }
}
